using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace FiveChess
{
    public class StateObject
    {
        // Size of receive buffer.
        public const int BufferSize = 2048;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();
    }

    class OnlinePlayer : IPlayer 
    {

        public event PlayerEventHandle playerEvent;

        private const int port = 11000;
        private Socket client;
        // The response from the remote device.
        private String response = String.Empty;

        /// <summary>
        /// 
        /// </summary>
        public OnlinePlayer() 
        {
            IPAddress ipAddress = IPAddress.Parse("192.168.68.1");
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
            client = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
            client.BeginConnect(remoteEP,new AsyncCallback(ConnectCallback), client);
        }

        private  void FireEvent(Point position)
        {
            if (playerEvent != null)
            {
                PlayerEventArgs args = new PlayerEventArgs(position);
                playerEvent(this, args);
            }
        }

        void IPlayer.GetNextChessmanPosition(Point pPoint)
        {

            Send(pPoint.ToString ());
        }

        public void Send(String data)
        {
            // Convert the string data to byte data using ASCII encoding.
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            // Begin sending the data to the remote device.
            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }

        private void SendCallback(IAsyncResult ar)
        {
                // Retrieve the socket from the state object.
                Socket lclient = (Socket)ar.AsyncState;
                // Complete sending the data to the remote device.
                int bytesSent = lclient.EndSend(ar);
                Receive();
        }

        private void ConnectCallback(IAsyncResult ar)
        {
                Socket lclient = (Socket)ar.AsyncState;
                lclient.EndConnect(ar);
        }

        private  void Receive()
        {
                // Create the state object.
                StateObject state = new StateObject();

                // Begin receiving the data from the remote device.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
        }

        private  void ReceiveCallback(IAsyncResult ar)
        {
                // Retrieve the state object and the client socket 
                // from the asynchronous state object.
                StateObject state = (StateObject)ar.AsyncState;

                // Read data from the remote device.
                int bytesRead = client.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There might be more data, so store the data received so far.
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                }
                else
                {
                    // All the data has arrived; put it in response.
                    if (state.sb.Length > 1)
                    {
                        response = state.sb.ToString();
                    }
                    // Signal that all bytes have been received.

                }
                Point position = new Point();
                    //test
                Random rand = new Random();

            
                position.X = rand.Next() % 15;
                position.Y = rand.Next() % 15;
                FireEvent(position);

        }

    }

}
